package tests;

import junit.framework.TestCase;

import org.junit.Test;

import util.HierarchyTree;

import application.Lock;
import application.LockTable;
import application.Parser;

public class ParserTest extends TestCase{

	private HierarchyTree<String> tree;
	private boolean debug = true;
	
	@Override
	protected void setUp() throws Exception{
		Parser.setDebug(debug);
		LockTable.setDebug(debug);
		Lock.setDebug(debug);
		HierarchyTree.setDebug(debug);
		
		tree = HierarchyTree.createHierarchyDefaultTree();
	}
	
	@Test
	public void testEscalonamento01(){
		String schedule = "r1x r2x w1x r3x c1 c3 c2";
		if(debug){
			System.out.println("Teste de escalonamento 1:");
			System.out.println("Scheduler: "+schedule);
		}
		Parser parser = new Parser(schedule, tree);
		String parsed = parser.parse();
		String parseCorreto = "r1x r2x w1x r3x c3 c2 c1";
		if(debug){
			System.out.println("Scheduler gerado: "+parsed+"\n");
			System.out.print(parsed.trim()+" == "+parseCorreto.trim());
			System.out.println(" > "+parsed.trim().equals(parseCorreto.trim()));
		}
		assertEquals(true, parsed.trim().equals(parseCorreto.trim()));
	}
	
	@Test
	public void testEscalonamento02(){
		String schedule = "w1x w2x w2y r3y r3z c1 c2 c3";
		if(debug){
			System.out.println("Teste de escalonamento 2:");
			System.out.println("Scheduler: "+schedule);
		}
		Parser parser = new Parser(schedule, tree);
		String parsed = parser.parse();
		String parseCorreto = "w1x r3y r3z c1 w2x w2y c3 c2";
		if(debug){
			System.out.println("Scheduler gerado: "+parsed+"\n");
			System.out.print(parsed.trim()+" == "+parseCorreto.trim());
			System.out.println(" > "+parsed.trim().equals(parseCorreto.trim()));
		}
		assertEquals(true, parsed.trim().equals(parseCorreto.trim()));
	}
	
	@Test
	public void testEscalonamento03(){
		String schedule = "w2x r3z r3x w1x r1z r3y w2z c3 w2z c2 c1";
		if(debug){
			System.out.println("Teste de escalonamento 2:");
			System.out.println("Scheduler: "+schedule);
		}
		Parser parser = new Parser(schedule, tree);
		String parsed = parser.parse();
		String parseCorreto = "w2x r3z r3x r3y w2z c3 w2z c2 w1x r1z c1";
		if(debug){
			System.out.println("Scheduler gerado: "+parsed+"\n");
			System.out.print(parsed.trim()+" == "+parseCorreto.trim());
			System.out.println(" > "+parsed.trim().equals(parseCorreto.trim()));
		}
		assertEquals(true, parsed.trim().equals(parseCorreto.trim()));
	}
	
	@Test
	public void testSequenciaEscalonamentos(){
		if(debug){
			System.out.println("Bateria de Testes:");
			System.out.println("> Teste 1");
		}
		
		String schedule1 = "r3y r1y r1x w1y c1 c3";
		String parsed1 = new Parser(schedule1, tree).parse();
		String resposta1 = "r3y r1y r1x w1y c3 c1";
		boolean teste1 = parsed1.trim().equals(resposta1.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed1+"\n");
			System.out.print(parsed1.trim()+" == "+resposta1.trim());
			System.out.println(" > "+parsed1.trim().equals(resposta1.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 2");
		}
		
		String schedule2 = "r1x r2x w3x c3 c2 c1";
		String parsed2 = new Parser(schedule2, tree).parse();
		String resposta2 = "r1x r2x w3x c2 c1 c3";
		boolean teste2 = parsed2.trim().equals(resposta2.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed2+"\n");
			System.out.print(parsed2.trim()+" == "+resposta2.trim());
			System.out.println(" > "+parsed2.trim().equals(resposta2.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 3");
		}
		
		String schedule3 = "r1x w1x w2x r2y w2y r3y w3y w4y c3 c4 r1z c1 c2";
		String parsed3 = new Parser(schedule3, tree).parse();
		String resposta3 = "r1x w1x r3y w3y c3 w4y c4 r1z c1 w2x r2y w2y c2";
		boolean teste3 = parsed3.trim().equals(resposta3.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed3+"\n");
			System.out.print(parsed3.trim()+" == "+resposta3.trim());
			System.out.println(" > "+parsed3.trim().equals(resposta3.trim()));
		}
		
		assertEquals(true, teste1 && teste2 && teste3);
	}
	
	@Test
	public void testEscalonamentosComDeadlock(){
		if(debug){
			System.out.println("Bateria de Testes:");
			System.out.println("> Teste 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule1 = "r1x r2x w1x w2x c1 c2";
		String parsed1 = new Parser(schedule1, tree).parse();
		String resposta1 = "r1x w1x c1";
		boolean teste1 = parsed1.trim().equals(resposta1.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed1+"\n");
			System.out.print(parsed1.trim()+" == "+resposta1.trim());
			System.out.println(" > "+parsed1.trim().equals(resposta1.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule2 = "r3y r1y r1x w1y r2y w3y c1 c3 r2z c2";
		String parsed2 = new Parser(schedule2, tree).parse();
		String resposta2 = "r3y r2y w3y r2z c2 c3";
		boolean teste2 = parsed2.trim().equals(resposta2.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed2+"\n");
			System.out.print(parsed2.trim()+" == "+resposta2.trim());
			System.out.println(" > "+parsed2.trim().equals(resposta2.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 3 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule3 = "r1x w2x r3x r1y r4z w2y r1v w3v r4v w4y w5y w5z c1 c2 c3 c4 c5"; 
		String parsed3 = new Parser(schedule3, tree).parse();
		String resposta3 = "r1x w2x r3x r1y w2y r1v w3v c1 c3 c2 w5y w5z c5";
		boolean teste3 = parsed3.trim().equals(resposta3.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed3+"\n");
			System.out.print(parsed3.trim()+" == "+resposta3.trim());
			System.out.println(" > "+parsed3.trim().equals(resposta3.trim()));
		}
		assertEquals(true, teste1 && teste2 && teste3);
		
		if(debug){
			System.out.println("\n> Teste 4 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule4 = "r1x w2x r3x r1y r4z w2y r1v w3v r4v w4y w5y w5z c1 c2 c3 c4 c5";
		String parsed4 = new Parser(schedule4, tree).parse();										
		String resposta4 = "r1x w2x r3x r1y w2y r1v w3v c1 c3 c2 w5y w5z c5";
		boolean teste4 = parsed4.trim().equals(resposta4.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed4+"\n");
			System.out.print(parsed4.trim()+" == "+resposta4.trim());
			System.out.println(" > "+parsed4.trim().equals(resposta4.trim()));
		}
		assertEquals(true, teste1 && teste2 && teste3 && teste4);
	}
	
	@Test
	public void testEscalonamentosComMultigranularidade(){
		if(debug){
			System.out.println("Bateria de Testes:");
			System.out.println("> Teste 1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule1 = "r1x w1pagina1 w2y c1 c2";
		String parsed1 = new Parser(schedule1, tree).parse();
		String resposta1 = "r1x w1pagina1 c1 w2y c2";
		boolean teste1 = parsed1.trim().equals(resposta1.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed1+"\n");
			System.out.print(parsed1.trim()+" == "+resposta1.trim());
			System.out.println(" > "+parsed1.trim().equals(resposta1.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule2 = "w3bd r1x w1bd w2y c1 c2 c3";
		String parsed2 = new Parser(schedule2, tree).parse();
		String resposta2 = "w3bd c3 r1x w1bd c1 w2y c2";
		boolean teste2 = parsed2.trim().equals(resposta2.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed2+"\n");
			System.out.print(parsed2.trim()+" == "+resposta2.trim());
			System.out.println(" > "+parsed2.trim().equals(resposta2.trim()));
		}
		
		if(debug){
			System.out.println("\n> Teste 3 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#");
		}
		
		String schedule3 = "w4bd r1pagina1 w1x w2y w4pagina1 c4 r3pagina1 c2 c1 c3";
		String parsed3 = new Parser(schedule3, tree).parse();
		String resposta3 = "w4bd w4pagina1 c4 r1pagina1 w1x c1 w2y c2 r3pagina1 c3 ";
		boolean teste3 = parsed3.trim().equals(resposta3.trim());
		if(debug){
			System.out.println("Scheduler gerado: "+parsed3+"\n");
			System.out.print(parsed3.trim()+" == "+resposta3.trim());
			System.out.println(" > "+parsed3.trim().equals(resposta3.trim()));
		}
		assertEquals(true, teste1 && teste2 && teste3);
	}
}
